<?php
/**
 * Page to Rule class
 *
 * @package eesc
 */ 

/**
 * Require rules
 */
require_once BASE_URI . "/lib/Database.class.php";
require_once BASE_URI . "/lib/Predicate.class.php";

/**
 * Rule Class
 *
 * Rules define the selections allowed made by an option
 * (e.g. Half subject, object A) using a list of predicates
 * (number of courses per category)
 *
 * $Rev:: 48            $:  Revision of last commit
 * $Author:: guy        $:  Author of last commit
 * $Date:: 2010-04-19 1#$:  Date of last commit
 * 
 * @package eesc
 * @subpackage classes
 */
class Rule {
	
	private $id;
	
	private $title;
	
	private $part;
	
	private $option;
	
	//private $ruletext;
	
	private $predicates = array();
	
	protected $db;
	
	/**
	 * Constructor
	 * 
	 * @param integer $id [optional] 
	 */
	public function __construct($id = NULL, $tripos = NULL)
	{	
	
		$this->db = new Database();
		$this->db->connect();
		
		if ($id != NULL) {
			$this->id = $id;
		} elseif ($tripos != NULL) {
			$ruleid = $this->db->select("rule","id", "WHERE tripos = " . $tripos);
			$this->id = $ruleid[0]["id"];
		}
		
	}
		
	/**
	 * Retrieve the entry from the database
	 * 
	 * @return string $entry
	 */
	public function __get($column) {
		$data = $this->db->select("rule",$column, "WHERE id = " . $this->id );
		$entry = $data[0][$column];
		return $entry;
	}
	
	public function __set($column, $entry) {
		return $this->db->update("rule",array("id" => $this->id),array($column=>$entry));
	}
	
	/**
	 * @see Database::getTable()
	 */
	public function getTable($format) {
		return $this->db->getTable(get_class($this), $format);
	}
	
	/**
	 * @see Database::add()
	 */
	public function add() {
		return $this->db->add(get_class($this));
	}
	
	/**
	 * @see Database::edit()
	 */
	public function edit($id) {
		$html = "<div id=\"ruledisplay\">";
		
		//$html .= $this;
		
		$html .= "</div>";
		
		
		$predicates = $this->db->select("Predicate","id");
		foreach ($predicates as $predicate) {
			$html .= "<div class=\"predicateboxes\" id=\"{$predicate['id']}\">";
			
			$myPredicate = new Predicate($predicate['id']);
			$html .= $myPredicate;
			
			$html .= "<p>(<a href=\"#\" class=\"predicateand\" predicate=\"{$predicate['id']}\">and</a> | <a href=\"#\" class=\"predicateor\" predicate=\"{$predicate['id']}\">or</a>)</p>";
			$html .= "</div>";
		}
		
		return $this->db->edit(get_class($this), $id) . $html;
		
	}
	
	/**
	 * @see Database::insert()
	 */
	public function insert($assoc_array) {
		return $this->db->insert(get_class($this), $assoc_array);
	}
	
	/**
	 * @see Database::update()
	 */
	public function update($id, $assoc_array) {
		return $this->db->update(get_class($this), array("id" => $id), $assoc_array);
	}
	
	/**
	 * @see Database::delete()
	 */
	public function delete($id) {
		return $this->db->delete(get_class($this), array("id" => $id));
	}

	
	/**
	 * Evaluates all the predicates in the rule against the $choices
	 * 
	 * @param array $choices
	 * @return boolean 
	 */
	public function evaluate(array $choices) {
		/*
		 * Set the predicate objects from the ruletext
		 */
		$space_seperated_predicates = str_ireplace(array("(",")","AND","OR"), "", $this->ruletext);
		$predicatesList = explode(" ",$space_seperated_predicates);
		foreach($predicatesList as $key => $value) {
			if($value == "" || $value == " " || is_null($value)) {
				unset($predicatesList[$key]);
			}
		}
		
		foreach ($predicatesList as $predicate) {
			$predicates["$predicate"] = new Predicate($predicate);
			
		}
		
		/*
		 * Extract the eval pattern
		 */
		$pattern = '/([0-9]+)/i';
		$replacement = '$predicates["$1"]->complies(\$choices)';
		$evaltext =  preg_replace($pattern, $replacement, $this->ruletext);
		

		//return based on evaluating the ruletext
		$all_comply = FALSE;
		$evaltext = "\$all_comply = " . $evaltext . ";";
		eval($evaltext);
		
		return $all_comply;
	}
	
	public function __toString() {
		/*
		 * Set the predicate objects from the ruletext
		 */
		$space_seperated_predicates = str_ireplace(array("(",")","AND","OR"), "", $this->ruletext);
		$predicatesList = explode(" ",$space_seperated_predicates);
		foreach($predicatesList as $key => $value) {
			if($value == "" || $value == " " || is_null($value)) {
				unset($predicatesList[$key]);
			}
		}
		//var_dump($predicatesList);
		foreach ($predicatesList as $predicate) {
			$predicates["$predicate"] = new Predicate($predicate);
		}
		
		/*
		 * Extract the eval pattern
		 */
		$pattern = '/([0-9]+)/i';
		$replacement = ' <div class="predicateboxes">" . $predicates["$1"] . "</div> ';
		$evaltext =  preg_replace($pattern, $replacement, $this->ruletext);
		$evaltext = "" . $evaltext . ";";
		
		//$evaltext = "<div class=\"predicateboxes\">( ( (  " . $predicates["1"] . "  AND  " . $predicates["2"] . "  ) OR  " . $predicates["1"] . "  )</div>";
		//return based on evaluating the ruletext
		return $evaltext;
	}
}